package com.ace.user.api.interceptor;

import com.ace.user.util.LogUtil;
import com.alibaba.fastjson.JSONObject;
import com.ace.user.api.annotation.AuthIgnore;
import com.ace.user.common.bean.RequestDTO;
import com.ace.user.common.bean.ResponseDTO;
import com.ace.user.common.bean.TokenDTO;
import com.ace.user.common.constant.C;
import com.ace.user.common.constant.Constants;
import com.ace.user.common.http.FeignTokenService;
import com.ace.user.config.locale.RLocale;
import com.ace.user.exception.BusinessException;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.MDC;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @author weihl
 * @date 2019/10/12 10:50
 */
@Slf4j
public class AuthorizationInterceptor implements HandlerInterceptor {

    @Resource
    private FeignTokenService feignTokenService;

    @Resource
    private RLocale rLocale;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        LogUtil.traceLogId();
        log.info("---> method:{} url->{} user-agent:{}", request.getMethod(),request.getRequestURI(),request.getHeader("User-Agent"));
        JSONObject jsonObject = new JSONObject();
        jsonObject.putAll(request.getParameterMap());
        log.info("params:{} lang:{}",jsonObject.toJSONString(),request.getSession().getAttribute("lang_session"));
        AuthIgnore annotation;
        if (handler instanceof HandlerMethod) {
            annotation = ((HandlerMethod) handler).getMethodAnnotation(AuthIgnore.class);
        } else {
            return true;
        }
        //如果有@IgnoreAuth注解，则不验证token
        if (annotation != null) {
            return true;
        }
        //从header中获取token
        String tokenValue = request.getHeader("token");
        //如果header中不存在token，则从参数中获取token
        if (tokenValue == null) {
            tokenValue = request.getParameter("token");
        }
        //token为空
        if (tokenValue == null) {
            throw new BusinessException( rLocale.getDTO("COMM_ERR_NO_TOKEN", C.T_C_8));
        }
        //验证token，如果验证通过则重置token有效时间
        RequestDTO<TokenDTO> param = new RequestDTO<>();
        param.setVersion("");
        param.setType("");
        TokenDTO checkToken = new TokenDTO().setValue(tokenValue).setActive(true);
        param.setData(checkToken);
        ResponseDTO result = feignTokenService.checkToken(param);
        if(!result.ok()){
            throw new BusinessException(new ResponseDTO(result.getMessage(), result.getCode()));
        }
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        long endTime = System.currentTimeMillis();
        long useTime = endTime - Long.parseLong(MDC.get(Constants.METHOD_START_TIME));
        log.info("<--- method:{} url{} useTime:{}ms",request.getMethod(),request.getRequestURI(),useTime);
    }
}
